主题
对比 JavaGuide《大模型结构化输出》、《MCP》、《Agent Skills》 与二哥《Agent 怎么知道该调用哪个工具?》《Agent 挂了几十个 Skill,怎么保证命中率?》,及小林《FC 原理》《Skill 是什么》《Tool Routing》《工具容错》。
多版对比
Function Calling 本质,JavaGuide 纠偏更准:FC 这名字有误导——模型只生成「调用意图」(工具名 + 参数 JSON),执行、权限、副作用全在业务侧执行层。二哥的七步流程是对的过程描述:全量工具定义塞 tools 字段 → LLM 返回 tool_calls(OpenAI 协议,各家兼容)→ 业务执行 → 结果回填 → 模型继续。他的口诀「描述定生死」是实战真理:模型选错工具,几乎都是工具 description 写得有歧义。
关系题(FC / MCP / Skill):JavaGuide 的口径最清楚——FC 产意图;MCP(JSON-RPC 2.0,Host/Client/Server)管工具的发现与连接标准化;Skill 是可复用的任务 SOP,本质是按需上下文注入,可以不调任何工具。三者不是层级关系。二哥补了一个真差异:Skill 靠自然语言语义匹配触发,工具走结构化的 schema 匹配。
命中率,实质分歧:二哥断言 Skill 选择「根本不走路由」,全靠 description 语义匹配,四招保命中(description 写触发关键词、单一职责、消除语义重叠、禁用误触场景);JavaGuide 恰好主张几十个 Skill 要上显式路由(粗召回 → 精排 → 低分不加载),依据是 Context Rot——全量定义塞上下文利用率会掉。两边其实统一于规模:Skill 少(一二十个以内)语义匹配够用,多了必须路由——这和记忆检索的结论同构。
各自独有:JavaGuide 有 tool_use_id 严格配对防并行调用错配、SKILL.md 正文 ≤500 行的渐进式披露;二哥有「未知工具报错回填后模型自修正」和 disable-model-invocation 防误触。
小林:恰好消解了二哥和 JavaGuide 的分歧——Skill 层靠三层渐进式加载(元数据仅 30-50 token/个 → 命中才载正文 → 资源用到才取)做自动发现,几十个 Skill 无压力(这站二哥);真正的「路由」问题在工具层:几十上百个工具才需要分层 Routing——注册表(含「何时不用」字段)→ 硬过滤(先鉴权再召回)→ 粗分类 → 混合检索 Top-K → 动态绑定候选 Schema 给 LLM 精选 → 执行前服务端再鉴权(这站 JavaGuide)。一句话:Skill 能帮着缩小工具候选,但不能替代权限过滤和执行鉴权。比喻链也好记:FC = 手、MCP = 厨房、Skill = 菜谱,逐层依赖不是竞争关系;错误信封要有 unknown 态(超时后不知成败,先查外部系统再重试)。
结论:原「分规模」结论升级为「分两层」——Skill 发现靠渐进式加载与语义匹配,工具多了才上分层路由;执行安全永远在服务端。
最优题解
Function Calling 的本质是模型产出「调用意图」:工具定义随请求下发,模型返回要调的工具名和参数,真正执行、权限、副作用全在我的代码里——所以工具安全永远不能只靠模型自觉。模型为什么选这个工具?只看工具的 description,所以「描述定生死」:选错工具十有八九是描述有歧义,参数错了会把报错回填让模型下一轮自修正。
Function Calling、MCP、Skill 不是三层楼:FC 是模型产意图的机制,MCP 是工具发现与连接的标准协议,Skill 是按需注入的任务手册,可以纯文本不调工具。Skill 挂多了怎么保命中?分规模——一二十个以内,把 description 写成「触发关键词 + 适用边界」,靠语义匹配就够;再多就必须上路由:先粗召回几个候选再精排,低分的不加载。本质都是上下文预算问题:全量塞进去,模型哪个都用不好。
追问链
追问:模型返回的工具参数怎么保证可用? 参考答:参数要过业务校验(schema + 业务规则),校验失败把错误信息回填给模型让它修——而不是直接执行或直接失败;高危操作再加确认和权限层。
追问:并行调用多个工具时结果怎么对应? 参考答:靠调用的唯一标识严格配对,回填时逐一对号,否则并发下结果错配,模型会拿 A 工具的结果当 B 的。
我的理解
这组题最值钱的是那句「模型只产意图,执行在我手里」——它把 FC 从「模型功能」还原成「协议约定」,安全、重试、幂等的讨论才有落点。命中率分歧的化解同记忆检索:规模决定方案。二哥的「描述定生死」是必留口诀,面试里说「我调过,选错工具基本都是描述写歧义了」比任何理论都可信。